#include "configuration_builder.h"
#include <QFileInfo>

namespace infrastructure {

// ========== ConfigurationBuilder 实现 ==========

ConfigurationBuilder::ConfigurationBuilder()
    : m_provider(std::make_shared<CompositeConfigurationProvider>())
    , m_basicValidatorAdded(false) {
}

ConfigurationBuilder& ConfigurationBuilder::addJsonFile(const QString& filePath, int priority, bool optional) {
    QFileInfo fileInfo(filePath);
    
    if (!optional && !fileInfo.exists()) {
        qWarning() << "配置文件不存在:" << filePath;
        return *this;
    }
    
    auto jsonProvider = std::make_shared<JsonFileProvider>(filePath, priority);
    m_provider->addProvider(jsonProvider);
    
    return *this;
}

ConfigurationBuilder& ConfigurationBuilder::addEnvironmentVariables(int priority) {
    auto envProvider = std::make_shared<EnvironmentVariableProvider>(priority);
    m_provider->addProvider(envProvider);
    
    return *this;
}

ConfigurationBuilder& ConfigurationBuilder::addEnvironmentVariables(const QString& prefix, int priority) {
    auto envProvider = std::make_shared<EnvironmentVariableProvider>(prefix, priority);
    m_provider->addProvider(envProvider);
    
    return *this;
}

ConfigurationBuilder& ConfigurationBuilder::addEnvironmentVariables(const QStringList& allowedKeys, int priority) {
    auto envProvider = std::make_shared<EnvironmentVariableProvider>(allowedKeys, priority);
    m_provider->addProvider(envProvider);
    
    return *this;
}

ConfigurationBuilder& ConfigurationBuilder::addProvider(std::shared_ptr<IConfigurationProvider> provider) {
    if (provider) {
        m_provider->addProvider(provider);
    }
    return *this;
}

ConfigurationBuilder& ConfigurationBuilder::addValidator(std::shared_ptr<IConfigurationValidator> validator) {
    if (validator) {
        m_provider->addValidator(validator);
    }
    return *this;
}

ConfigurationBuilder& ConfigurationBuilder::addBasicValidation() {
    ensureBasicValidator();
    return *this;
}

ConfigurationBuilder& ConfigurationBuilder::requireKey(const QString& key, const QString& message) {
    ensureBasicValidator();
    m_basicValidator->addRequiredKey(key, message);
    return *this;
}

ConfigurationBuilder& ConfigurationBuilder::validateType(const QString& key, QVariant::Type expectedType, const QString& message) {
    ensureBasicValidator();
    m_basicValidator->addTypeCheck(key, expectedType, message);
    return *this;
}

ConfigurationBuilder& ConfigurationBuilder::validateRange(const QString& key, const QVariant& min, const QVariant& max, const QString& message) {
    ensureBasicValidator();
    m_basicValidator->addRangeCheck(key, min, max, message);
    return *this;
}

ConfigurationBuilder& ConfigurationBuilder::validateLength(const QString& key, int minLength, int maxLength, const QString& message) {
    ensureBasicValidator();
    m_basicValidator->addLengthCheck(key, minLength, maxLength, message);
    return *this;
}

ConfigurationBuilder& ConfigurationBuilder::validatePattern(const QString& key, const QString& pattern, const QString& message) {
    ensureBasicValidator();
    m_basicValidator->addPatternCheck(key, pattern, message);
    return *this;
}

ConfigurationBuilder& ConfigurationBuilder::validateCustom(const QString& key, std::function<bool(const QVariant&)> validator, const QString& message) {
    ensureBasicValidator();
    m_basicValidator->addCustomCheck(key, validator, message);
    return *this;
}

std::shared_ptr<CompositeConfigurationProvider> ConfigurationBuilder::build() {
    return m_provider;
}

ConfigurationBuilder ConfigurationBuilder::createDefault(const QString& appConfigPath) {
    ConfigurationBuilder builder;
    
    // 默认配置源优先级：
    // 1. 环境变量 (优先级 300)
    // 2. JSON配置文件 (优先级 200)
    
    if (!appConfigPath.isEmpty()) {
        builder.addJsonFile(appConfigPath, 200, true);  // 可选的
    }
    
    builder.addEnvironmentVariables("APP", 300);
    builder.addBasicValidation();
    
    return builder;
}

ConfigurationBuilder ConfigurationBuilder::createFromJsonFile(const QString& filePath) {
    ConfigurationBuilder builder;
    builder.addJsonFile(filePath, 100);
    builder.addBasicValidation();
    return builder;
}

ConfigurationBuilder ConfigurationBuilder::createWithEnvironmentOnly(const QString& prefix) {
    ConfigurationBuilder builder;
    
    if (prefix.isEmpty()) {
        builder.addEnvironmentVariables(100);
    } else {
        builder.addEnvironmentVariables(prefix, 100);
    }
    
    builder.addBasicValidation();
    return builder;
}

void ConfigurationBuilder::ensureBasicValidator() {
    if (!m_basicValidatorAdded) {
        m_basicValidator = std::make_shared<BasicConfigurationValidator>();
        m_provider->addValidator(m_basicValidator);
        m_basicValidatorAdded = true;
    }
}

// ========== ConfigurationFactory 实现 ==========

namespace ConfigurationFactory {

std::shared_ptr<kernel::IConfiguration> createDefault(const QString& appConfigPath) {
    return ConfigurationBuilder::createDefault(appConfigPath).build();
}

std::shared_ptr<kernel::IConfiguration> fromJsonFile(const QString& filePath) {
    return ConfigurationBuilder::createFromJsonFile(filePath).build();
}

std::shared_ptr<kernel::IConfiguration> fromEnvironmentVariables(const QString& prefix) {
    return ConfigurationBuilder::createWithEnvironmentOnly(prefix).build();
}

std::shared_ptr<kernel::IConfiguration> createForTesting(const QHash<QString, QVariant>& testData) {
    // 创建一个用于测试的内存配置提供者
    class TestConfigurationProvider : public IConfigurationProvider {
    public:
        explicit TestConfigurationProvider(const QHash<QString, QVariant>& data) : m_data{data} {}
        
        ConfigurationData load() override {
            ConfigurationData result;
            result.values = m_data;
            return result;
        }
        
        bool isAvailable() const override { return true; }
        QString getDescription() const override { return "测试配置提供者"; }
        void setChangeCallback(ConfigurationChangeCallback) override {}
        void startWatching() override {}
        void stopWatching() override {}
        int getPriority() const override { return 100; }
        
    private:
        QHash<QString, QVariant> m_data;
    };
    
    ConfigurationBuilder builder;
    auto testProvider = std::make_shared<TestConfigurationProvider>(testData);
    builder.addProvider(testProvider);
    
    return builder.build();
}

} // namespace ConfigurationFactory

} // namespace infrastructure 